﻿#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <vector>
using namespace std;

struct Point
{
	int _x;
	int _y;
};

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}

	Date(const Date& d)
		:_year(d._year)
		, _month(d._month)
		, _day(d._day)
	{
		cout << "Date(const Date& d)" << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

//int main()
//{
//	// C++98⽀持的
//	int a1[] = { 1, 2, 3, 4, 5 };
//	int a2[5] = { 0 };
//	Point p = { 1, 2 };
//
//	// C++11⽀持的
//	int x = { 1 };
//	int x1{ 3 };
//
//	Date d = { 2025, 1, 1 }; // 没有调用拷贝构造
//	Date d1{ 2025, 1, 2 }; // 没有调用拷贝构造
//	// 这⾥d2引⽤的是{ 2024, 10, 31 }构造的临时对象
//	const Date& d2 = { 2024, 10, 31 }; // 没有调用拷贝构造
//
//	// 需要注意的是C++98⽀持单参数时类型转换，也可以不⽤{}
//	Date d3 = { 2025 }; // 没有调用拷贝构造
//	Date d4 = 2025; // 没有调用拷贝构造
//
//	vector<Date> s;
//	// ⽐起有名对象和匿名对象传参，这⾥{}更有性价⽐
//	s.push_back(Date{ 2025, 1, 1 });
//
//	Date d5 = { 2025, 3, 3 };
//	vector<int> f = { 1,2,3,4,5,6,7,8,9,0 };
//
//	return 0;
//}


void test_lvalues() 
{
	// 变量
	int a = 10;                    // a是左值

	// 数组元素
	int arr[5];
	arr[0] = 1;                    // arr[0]是左值

	// 类对象成员
	struct Point { int x, y; };
	Point p;
	p.x = 10;                      // p.x是左值

	// 解引用
	int* ptr = &a;
	*ptr = 20;                     // *ptr是左值

	// 字符串字面量（特殊情况）
	const char* str = "hello";     // "hello"是左值
	// &"hello";                   // ✓ 可以取地址
}

int getValue() { return 100; }
void test_rvalues() 
{
	// 字面量
	int a = 42; // 42是右值
	double b = 3.14; // 3.14是右值
	bool flag = true; // true是右值

	// 算术表达式
	int x = 10, y = 20;
	int sum = x + y; // (x + y)是右值

	// 函数返回值（非引用）
	int val = getValue(); // getValue()是右值

	// 临时对象
	std::string s = std::string("temp");  // std::string("temp")是右值
	std::vector<int> v = std::vector<int>{ 1,2,3 }; // 临时vector是右值
}
//int main()
//{
//	int x = 5;
//
//	// const左值引用可以引用右值
//	const int& cr1 = 10;
//	const int& cr2 = x + 5;
//
//	int y = 10;
//
//	// 没有move时：右值引用不能绑定左值
//	// int&& r1 = y;
//
//	// 使用move后：将左值转为右值引用
//	int&& r2 = move(y);
//	cout << "y = " << y << endl;
//	cout << "r2 = " << r2 << endl;
//	r2 = 20;
//	cout << "y = " << y << endl;
//
//	return 0;
//}

void process(int& val) { cout << "lvalue\n"; }
void process(int&& val) { cout << "rvalue\n"; }

//int main()
//{
//	int&& rr1 = 10;  // rr1本身是左值！
//
//	// 验证：
//	int* p = &rr1;           // ✓ 可以取地址 - 证明rr1是左值
//	// int* p2 = &10;        // ❌ 不能取字面量的地址
//
//	// 函数重载测试
//	process(rr1);            // 输出: lvalue (不是rvalue!)
//	process(10);             // 输出: rvalue
//
//	return 0;
//}

//int main()
//{
//	int i = 0;
//	int& r1 = i;
//	int& r2 = r1;
//
//	int&& rr1 = 10;
//	// 无法将左值绑定到右值引用
//	//int&& rr2 = rr1;
//
//	return 0;
//}

//void f(int& x)
//{
//	cout << "左值引用重载 f(" << x << ")\n";
//}
//void f(const int& x)
//{
//	cout << "到 const 的左值引用重载 f(" << x << ")\n";
//}
//void f(int&& x)
//{
//	cout << "右值引用重载 f(" << x << ")\n";
//}

//int main()
//{
//	int i = 1;
//	const int ci = 2;
//	f(i); // 调⽤ f(int&)
//	f(ci); // 调⽤ f(const int&)
//	f(3); // 调⽤ f(int&&)，如果没有 f(int&&) 重载则会调⽤ f(const int&)
//	f(std::move(i)); // 调⽤ f(int&&)
//
//	return 0;
//}


namespace STR
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		
		string(const string& s)
		{
			cout << "string(const string& s) -- 拷贝构造" << endl;
			_str = new char[s._capacity + 1];
			memcpy(_str, s._str, s._size + 1);
			_size = s._size;
			_capacity = s._capacity;
		}

		// 移动构造
		string(string&& s)
		{
			cout << "string(const string&& s) -- 移动构造" << endl;
			swap(s);
		}

		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 拷贝赋值" << endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}
			return *this;
		}

		// 移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			swap(s);
			return *this;
		}

		~string()
		{
			//cout << "~string() -- 析构" << endl;
			delete[] _str;
			_str = nullptr;
		}
		char& operator[](size_t pos)
		{
			return _str[pos];
		}

		void reserve(size_t n)
		{
			cout << "_capacity:" << _capacity << endl;
			if (n > _capacity)
			{
				char* str = new char[n + 1];
				memcpy(str, _str, _size + 1);
				delete[] _str;
				_str = str;
				_capacity = n;
			}
		}
		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				int newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			_size++;
			_str[_size] = '\0';
		}

		private:
			char* _str = nullptr;
			size_t _size = 0;
			size_t _capacity = 0;
	};
}


//int main()
//{
//	STR::string s1("xxxxx");
//	// 拷⻉构造
//	STR::string s2 = s1;
//	// 构造 + 拷贝构造，编译器优化为直接构造
//	STR::string s3 = STR::string("yyyyy");
//	STR::string s4 = move(s1);
//
//	return 0;
//}

//int main()
//{
//	STR::string s1("xxxxx");
//	// 拷⻉构造
//	STR::string s2 = s1;
//	// 构造+移动构造，优化后直接构造
//	STR::string s3 = STR::string("yyyyy");
//	// 移动构造
//	STR::string s4 = move(s1); 
//
//	return 0;
//}

//int main()
//{
//	STR::string s5("yyyyyyyyyyyyyyyyy");
//	STR::string s3 = s5;
//	s5 = STR::string("yyyyy");
//
//	return 0;
//}

//int main()
//{
//	typedef int& lref;
//	using rref = int&&; // 和上面等价
//
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//	rref&& r4 = 1; // r4 的类型是 int&&
//
//	return 0;
//}

// 由于引⽤折叠限定，f1实例化以后总是⼀个左值引⽤
template<class T>
void f1(T& x)
{ }


//int main()
//{
//	int n = 1;
//
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0); // 左值引用，报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0); // 左值引用，报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0); // 左值引用，报错
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0); // 可接收右值
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0); // 可接收右值
//
//	return 0;
//}

// 由于引⽤折叠限定，f2实例化后可以是左值引⽤，也可以是右值引⽤
template<class T>
void f2(T&& x)
{ }

//int main()
//{
//	int n = 1;
//	// 没有折叠->实例化为void f2(int&& x)
//	//f2<int>(n); // 右值引用，报错
//	f2<int>(0);
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	//f2<int&>(0); // 左值引用，报错
//	// 折叠->实例化为void f2(int&& x)
//	//f2<int&&>(n); // 右值引用，报错
//	f2<int&&>(0);
//
//	return 0;
//}

//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//
//	cout << "&a = " << &a << endl;
//	cout << "&x = " << &x << endl << endl;
//}

//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//
//	return 0;
//}

//int main()
//{
//	int a = 1;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//
//	return 0;
//}

//template<class T>
//class func
//{
//	// ...
//	// 万能引用
//	template<class Y>
//	void Function(Y&& t)
//	{
//		int a = 0;
//		Y x = a;
//
//		cout << "&a = " << &a << endl;
//		cout << "&x = " << &x << endl << endl;
//	}
//	// ...
//};

//int main()
//{
//	//const int b = 9;
//	//// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&t)
//	//Function(b);
//
//
//	return 0;
//}

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }

// 万能引用
template<class T>
void Function(T&& t)
{
	//Fun(t);
	// 完美转发
	Fun(forward<T>(t));
}

//int main()
//{
//	// 模板实例化为void Function(int&& t)
//	Function(10); // 右值
//
//	int a;
//	// 模板实例化为void Function(int& t)
//	Function(a); // 左值
//
//	// 模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//	const int b = 8;
//
//	// 模板实例化为void Function(const int& t)
//	Function(b);
//
//	// 模板实例化为void Function(const int&& t)
//	Function(std::move(b)); // const 右值
//
//	return 0;
//}


//int main()
//{
//	string s{};
//	int k{};
//	int n{};
//	cout << s << endl;
//	cout << k << endl;
//	cout << n << endl;
//
//	return 0;
//}

//template <class ...Args> void Func(Args... args) {}
//template <class ...Args> void Func(Args&... args) {}
//template <class ...Args> void Func(Args&&... args) {}

//template <class ...Args>
//void Print(Args... args)
//{
//	// 使用运算符 sizeof... 计算
//	cout << sizeof...(args) << endl;
//}
//
//int main()
//{
//	double x = 2.2;
//	Print(); // 包⾥有0个参数
//	Print(1); // 包⾥有1个参数
//	Print(1, string("xxxxx")); // 包⾥有2个参数
//	Print(1.1, string("xxxxx"), x); // 包⾥有3个参数
//
//	return 0;
//}

//void Print();
//void Print(int&& arg1);
//void Print(int&& arg1, string&& arg2);
//void Print(double&& arg1, string&& arg2, double& arg3);

// 原理2：更本质去看没有可变参数模板，我们实现出这样的多个函数模板才能⽀持
// 这⾥的功能，有了可变参数模板，我们进⼀步被解放，他是类型泛化基础
// 上叠加数量变化，让我们泛型编程更灵活。

//void Print();
//template <class T1>
//void Print(T1&& arg1);
//template <class T1, class T2>
//void Print(T1&& arg1, T2&& arg2);
//template <class T1, class T2, class T3>
//void Print(T1&& arg1, T2&& arg2, T3&& arg3);

void ShowList()
{
	cout << endl;
}

template<class T, class ...Args>
void ShowList(T x, Args... args)
{
	cout << x << " ";
	ShowList(args...);
}

template <class ...Args>
void Print(Args... args)
{
	ShowList(args...);
}

//int main()
//{
//	double x = 2.2;
//	Print(); // 包⾥有0个参数
//	Print(1); // 包⾥有1个参数
//	Print(1, string("hello world")); // 包⾥有2个参数
//	Print(1.1, string("hello world"), x); // 包⾥有3个参数
//
//	return 0;
//}


//int  main()
//{
//	// 场景1：push_back现有对象
//	std::string str = "这是一个很长的字符串，会触发深拷贝";
//	std::vector<std::string> vec;
//	vec.push_back(str);  // 深拷贝发生！
//	// 场景2：push_back临时对象  
//	std::vector<std::string> vec;
//	vec.push_back(std::string("临时字符串"));  // 构造+移动
//	// 场景3：emplace_back
//	std::vector<std::string> vec;
//	vec.emplace_back("直接构造的字符串");  // 直接构造，无拷贝
//
//	return 0;
//}

//class Example {
//public:
//	Example(int a, int b)
//		:_x(a)
//		,_y(b)
//	{
//		cout << "目标构造函数，被委托的函数\n";
//	}
//
//	//Example(int a)
//	//	: Example(a, 0)
//	//	,_y(1) // 不能
//	//{
//	//	cout << "委托构造函数\n";
//	//}
//
//	Example(int a)
//		: Example(a, 0)
//	{
//		cout << "委托构造函数\n";
//	}
//
//	int _x;
//	int _y;
//};
//
//int main()
//{
//	Example(1, 2);
//	Example(1);
//
//	return 0;
//}
//
//class Time {
//public:
//	Time(int h, int m)
//		:_hour(h)
//		, _minute(m)
//	{
//	}
//
//	// error C3511: “Time”: 对委托构造函数的调用应仅为成员初始值设定项
//	// error C2437 : “_second”: 已初始化
//	/*Time(int h, int m, int s)
//		:Time(h, m)
//		, _second(s)
//	{}*/
//
//private:
//	int _hour;
//	int _minute;
//	int _second = 0;
//};

class Base 
{
public:
	Base(int x, double d)
		:_x(x)
		, _d(d)
	{ }

	Base(int x)
		:_x(x)
	{ }

	Base(double d)
		:_x(d)
	{ }

protected:
	int _x = 0;
	double _d = 0;
};

// 传统的派生类实现构造
//class Derived : public Base 
//{
//public:
//	Derived(int x) : Base(x) {}
//	Derived(double d) : Base(d) {}
//	Derived(int x, double d) : Base(x, d) {}
//protected:
//	int _i;
//	string _s;
//};

// C++11继承基类的所有构造函数
// 1、没有成员变量的派生类
// 2、成员变量都有缺省值，并且我们就想用这个缺省值初始化
//
class Derived : public Base 
{
public:
	using Base::Base;

protected:
	int _i;
	string _s;
};

//int main()
//{
//	//Derived d;
//	Derived d1(1);
//	Derived d2(1.1);
//	Derived d3(2, 2.2);
//
//	return 0;
//}

//int main()
//{
//	// 匿名函数对象
//	/*[](int x, int y)->int
//	{
//		return x + y;
//	};*/
//
//	auto add = [](int x, int y)->int {return x + y; };
//	/*cout << add(1, 2) << endl;*/
//
//	// 1、捕捉列表为空也不能省略
//	// 2、函数体为空也不能省略
//	// 3、返回值通常省略，让编译器自动推导
//	// 4、参数列表为空可以省略
//	auto func = []
//	{
//		cout << "hello world!" << endl;
//		return 0;
//	};
//	func();
//
//	return 0;
//}

#include <algorithm>

struct Goods
{
	string _name; // 名字
	double _price; // 价格
	int _eval; // 评价

	Goods(const char* str, double price, int eval)
		:_name(str)
		, _price(price)
		, _eval(eval)
	{ }
};

//struct PriceCmp
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	}
//};
//
//struct EvalCmp
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._eval < gr._eval;
//	}
//};

void print(const vector<Goods>& s)
{
	for (auto& e : s)
	{
		cout << e._name << " " << e._price << " " << e._eval << endl;
	}
	cout << endl;
}

//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "柚子", 5.3, 4 }, { "橙子", 2.2, 3}, { "菠萝", 1.5, 4 }};
//
//	//sort(v.begin(), v.end(), PriceCmp());
//	//print(v);
//	//sort(v.begin(), v.end(), EvalCmp());
//	//print(v);
//
//	/*auto PriceCmp = [](const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	};
//	sort(v.begin(), v.end(), PriceCmp);*/
//
//
//
//
//	sort(v.begin(), v.end(), [](const Goods& gl, const Goods& gr){
//			return gl._price < gr._price;
//		});
//	print(v);
//	sort(v.begin(), v.end(), [](const Goods& gl, const Goods& gr){
//		return gl._eval < gr._eval;
//		});
//	print(v);
//
//	return 0;
//}


//int main()
//{
//	//int a = 0, b = 3;
//	//auto func = [a, &b]
//	//{
//	//	// 值捕捉的变量不能修改，引⽤捕捉的变量可以修改
//	//	// a++;
//	//	b++;
//	//	return a + b;
//	//};
//
//	//cout << func() << endl;
//	//cout << "b: " << b << endl;
//
//	int a = 0, b = 3, c = 2;
//	// 隐式值捕捉
//	auto func1 = [=]
//	{
//		// 用了哪些变量就捕捉哪些变量
//		return (a + b) * c;
//	};
//	cout << func1() << endl;
//	// 隐式引用捕捉
//	auto func2 = [&]
//	{
//		// 用了哪些变量就捕捉哪些变量
//		a++, b++, c++;
//	};
//	func2();
//	cout << "a: " << a << " b: " << b << " c: " << c;
//
//	return 0;
//}

//int x = 0;
//// 捕捉列表必须为空
//// 因为全局变量不用捕捉就可以用，没有可被捕捉的变量
//auto func = []()
//{
//	x++;
//};
//
//int main()
//{
//	//...
//	func();
//
//	return 0;
//}

//int main()
//{
//	int a = 0, b = 3, c = 5;
//	// mutable相当于去掉const属性，可以修改了
//	auto func = [=]() mutable
//	{
//		a++;
//		b++;
//		c++;
//		cout << "a: " << a << " b: " << b << " c: " << c << endl;
//	};
//	func();
//	cout << "a: " << a << " b: " << b << " c: " << c << endl;
//
//	return 0;
//}


class Rate
{
public:
	Rate(double rate)
		: _rate(rate)
	{ }
	double operator()(double money, int year)
	{
		return money * _rate * year;
	}
private:
	double _rate;
};

//int main()
//{
//	double r = 0.89;
//	// lambda
//	auto r1 = [r](double money, int year) {
//		return money * r * year;
//	};
//	// 函数对象
//	Rate r2(r);
//	r1(10000, 3); // lambda
//	r2(10000, 3); // 仿函数类对象
//
//	return 0;
//}

//#include <functional>

//int f(int a, int b){ return a + b; }
//
//struct func
//{
//public:
//	int operator() (int a, int b){ return a + b; }
//};
//
//int main()
//{
//	// 包装各种可调⽤对象
//	
//	function<int(int, int)> f2 = func();
//	function<int(int, int)> f3 = [](int a, int b) {return a + b; };
//	function<int(int, int)> f1 = f;
//	cout << f1(1, 1) << endl;
//	cout << f2(1, 1) << endl;
//	cout << f3(1, 1) << endl;
//
//	return 0;
//}

//class Plus
//{
//public:
//	static int add(int a, int b){ return a + b; }
//	int plus1(int a, int b) { return a + b; }
//};

//int main()
//{
//	// 包装静态成员函数
//	// 成员函数要指定类域并且前面加&才能获取地址
//	/*function<int(int, int)> f4 = &Plus::add;
//	cout << f4(1, 1) << endl;*/
//
//	// 包装普通成员函数
//	// 普通成员函数还有一个隐含的this指针参数，所以绑定时传对象或者对象的指针过去都可以
//	function<int(Plus*, int, int)> f5 = &Plus::plus1;
//	Plus ps;
//	cout << f5(&ps, 1, 1) << endl;
//	function<int(Plus, int, int)> f6 = &Plus::plus1;
//	cout << f6(Plus(), 1, 1) << endl;
//	function<int(Plus&, int, int)> f7 = &Plus::plus1;
//	cout << f7(ps, 1, 1) << endl;
//	function<int(Plus&&, int, int)> f8 = &Plus::plus1;
//	cout << f8(Plus(), 1, 1) << endl;
//
//	return 0;
//}

//#include <functional>
//
//using placeholders::_1;
//using placeholders::_2;
//using placeholders::_3;
//
//int Sub(int a, int b)
//{
//	return a - b;
//}

//int main()
//{
//	cout << Sub(7, 2) << endl;
//
//	//          修改参数顺序
//	auto Sub1 = bind(Sub, _1, _2);
//	cout << "Sub1: " << Sub1(8, 2) << endl;
//
//	auto Sub2 = bind(Sub, _2, _1);
//
//	cout << "Sub2: " << Sub2(8, 2) << endl;
//
//	return 0;
//}

#include <functional>

using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
	return a - b;
}

//int main()
//{
//	// 调整参数个数
//	auto Sub1 = bind(Sub, _1, 10);
//	cout << "Sub1: " << Sub1(19) << endl;
//
//	auto Sub2 = bind(Sub, 7, _1);
//
//	cout << "Sub2: " << Sub2(16) << endl;
//
//	return 0;
//}

class Plus
{
public:
	static int add(int a, int b) { return a + b; }
	int plus1(int a, int b) { return a + b; }
};

int main()
{
	// 包装静态成员函数
	// 成员函数要指定类域并且前面加&才能获取地址
	/*function<int(int, int)> f4 = &Plus::add;
	cout << f4(1, 1) << endl;*/

	// 包装普通成员函数
	// 普通成员函数还有一个隐含的this指针参数，所以绑定时传对象或者对象的指针过去都可以
	/*function<int(Plus*, int, int)> f5 = &Plus::plus1;
	Plus ps;
	cout << f5(&ps, 1, 1) << endl;
	function<int(Plus, int, int)> f6 = &Plus::plus1;
	cout << f6(Plus(), 1, 1) << endl;
	function<int(Plus&, int, int)> f7 = &Plus::plus1;
	cout << f7(ps, 1, 1) << endl;*/
	/*function<int(Plus&&, int, int)> f8 = &Plus::plus1;
	cout << f8(Plus(), 1, 1) << endl;*/

	auto f = bind(&Plus::plus1, Plus(), _1, _2);
	cout << f(1, 5) << endl;

	function<int(int, int)> f1 = bind(&Plus::plus1, Plus(), _1, _2);
	cout << f1(1, 5) << endl;

	return 0;
}
